package org.springcloud.plugin.stragegy.sentinel.loader;

import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springcloud.plugin.framework.adapter.CoreAdapter;
import org.springcloud.plugin.stragegy.sentinel.constant.SentinelStrategyConstant;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @Author yanggld
 * @Date 2020/1/10-10:54
 * @Description
 */
@Slf4j
public abstract class SentinelDataSourceRuleLoader extends SentinelFileRuleLoader {

	@Autowired
	protected CoreAdapter codeAdapter;

	@Override
	public void load() {
		initialize();

		String groupKey = "key";
		String group = codeAdapter.getGroup();
		String serviceId = codeAdapter.getServiceId();

		log.info("Subscribe flow rules from {} server, {}={}, serviceId={}", getConfigType(), groupKey, group, serviceId + "-" + SentinelStrategyConstant.SENTINEL_FLOW_KEY);
		ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = getFlowRuleDataSource();
		FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
		log.info("{} flow rules form datasource loaded...", FlowRuleManager.getRules().size());

		log.info("Subscribe degrade rules from {} server, {}={}, serviceId={}", getConfigType(), groupKey, group, serviceId + "-" + SentinelStrategyConstant.SENTINEL_DEGRADE_KEY);
		ReadableDataSource<String, List<DegradeRule>> degradeRuleDataSource = getDegradeRuleDataSource();
		if (degradeRuleDataSource != null) {
			DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());
			log.info("{} degrade rules form datasource loaded...", DegradeRuleManager.getRules().size());
		}

		log.info("Subscribe authority rules from {} server, {}={}, serviceId={}", getConfigType(), groupKey, group, serviceId + "-" + SentinelStrategyConstant.SENTINEL_AUTHORITY_KEY);
		ReadableDataSource<String, List<AuthorityRule>> authorityRuleDataSource = getAuthorityRuleDataSource();
		if (authorityRuleDataSource != null) {
			AuthorityRuleManager.register2Property(authorityRuleDataSource.getProperty());
			log.info("{} authority rules form datasource loaded...", AuthorityRuleManager.getRules().size());
		}

		log.info("Subscribe system rules from {} server, {}={}, serviceId={}", getConfigType(), groupKey, group, serviceId + "-" + SentinelStrategyConstant.SENTINEL_SYSTEM_KEY);
		ReadableDataSource<String, List<SystemRule>> systemRuleDataSource = getSystemRuleDataSource();
		if (systemRuleDataSource != null) {
			SystemRuleManager.register2Property(systemRuleDataSource.getProperty());
			log.info("{} system rules form datasource loaded...", SystemRuleManager.getRules().size());
		}

		log.info("Subscribe param flow rules from {} server, {}={}, serviceId={}", getConfigType(), groupKey, group, serviceId + "-" + SentinelStrategyConstant.SENTINEL_PARAM_FLOW_KEY);
		ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleDataSource = getParamFlowRuleDataSource();
		if (paramFlowRuleDataSource != null) {
			ParamFlowRuleManager.register2Property(paramFlowRuleDataSource.getProperty());
			log.info("{} param flow rules form datasource loaded...", ParamFlowRuleManager.getRules().size());
		}

		super.load();
	}

	public abstract void initialize();

	public abstract ReadableDataSource<String, List<FlowRule>> getFlowRuleDataSource();

	public abstract ReadableDataSource<String, List<DegradeRule>> getDegradeRuleDataSource();

	public abstract ReadableDataSource<String, List<AuthorityRule>> getAuthorityRuleDataSource();

	public abstract ReadableDataSource<String, List<SystemRule>> getSystemRuleDataSource();

	public abstract ReadableDataSource<String, List<ParamFlowRule>> getParamFlowRuleDataSource();

	public abstract String getConfigType();
}
